Splitting up a JSON from mqtt

Hi everyone, would love to get some help how to do this if it’s at all possible!
The Swedish weather service has an API that I manage to call using node-red and filter out the latest values from their huge json response so it looks like this:

{“validTime”:“2018-02-12T19:00:00Z”,“parameters”:[{“name”:“msl”,“levelType”:“hmsl”,“level”:0,“unit”:“hPa”,“values”:[1001.7]},{“name”:“t”,“levelType”:“hl”,“level”:2,“unit”:“Cel”,“values”:[0.6]},{“name”:“vis”,“levelType”:“hl”,“level”:2,“unit”:“km”,“values”:[22]},{“name”:“wd”,“levelType”:“hl”,“level”:10,“unit”:“degree”,“values”:[233]},{“name”:“ws”,“levelType”:“hl”,“level”:10,“unit”:“m/s”,“values”:[5.1]},{“name”:“r”,“levelType”:“hl”,“level”:2,“unit”:“percent”,“values”:[94]},{“name”:“tstm”,“levelType”:“hl”,“level”:0,“unit”:“percent”,“values”:[1]},{“name”:“tcc_mean”,“levelType”:“hl”,“level”:0,“unit”:“octas”,“values”:[8]},{“name”:“lcc_mean”,“levelType”:“hl”,“level”:0,“unit”:“octas”,“values”:[8]},{“name”:“mcc_mean”,“levelType”:“hl”,“level”:0,“unit”:“octas”,“values”:[0]},{“name”:“hcc_mean”,“levelType”:“hl”,“level”:0,“unit”:“octas”,“values”:[0]},{“name”:“gust”,“levelType”:“hl”,“level”:10,“unit”:“m/s”,“values”:[11]},{“name”:“pmin”,“levelType”:“hl”,“level”:0,“unit”:“kg/m2/h”,“values”:[0]},{“name”:“pmax”,“levelType”:“hl”,“level”:0,“unit”:“kg/m2/h”,“values”:[0.2]},{“name”:“spp”,“levelType”:“hl”,“level”:0,“unit”:“percent”,“values”:[73]},{“name”:“pcat”,“levelType”:“hl”,“level”:0,“unit”:“category”,“values”:[1]},{“name”:“pmean”,“levelType”:“hl”,“level”:0,“unit”:“kg/m2/h”,“values”:[0.1]},{“name”:“pmedian”,“levelType”:“hl”,“level”:0,“unit”:“kg/m2/h”,“values”:[0.1]},{“name”:“Wsymb2”,“levelType”:“hl”,“level”:0,“unit”:“category”,“values”:[6]}]}

Is it possible to make a mqtt sensor for this json that for each picks out the name, unit and value?

I think it is not a valid JSON… If it is a valid json, you can write an automation that can parse JSON and load into sensors automatically. I’ve something similar to this here https://github.com/skalavala/smarthome/blob/master/packages/zwave_batteries.yaml#L105-L155

Please use http://wwwjsonlint.com to check if the json is valid or not.

Thanks for the tip, jsonlint says it’s a valid json so I guess it should be ok. I’ll check that automation to!

It was giving me error when I tried the above json… may be it converted the quotes to wrong type… If you use ``` before and after pasting code, it maintains the format.

It will be fun to parse and load the data into sensors… good luck!

Yes, examples of how to do this are here

The best way of checking the decoding of json is by using the templates page of the developer tools. Paste your json inside my_test_json and you can try various ways of extracting it.

I’ve tried some more now, the json looks like this after beautifying it: https://pastebin.com/9SMEsNTT (sorry, didnt get preformatted text to work)
Pasted that into the template part of hass, read some in the templating docs about nested Json but when I enter
'{{ value_json["parameters"]["temp"] }}' below it I keep getting an error with Error rendering template: UndefinedError: 'value_json' is undefined?

Thanks, I was able to load your json this time, and when I looked into it, I don’t see any attribute called temp in the parameters array. What value are you trying to extract from the JSON?

Here is how you can access individual attribute values:

Name: {{ value_json.parameters[0].name }}
Level Type: {{ value_json.parameters[0].levelType }}
Level: {{ value_json.parameters[0].level }}
Unit: Level: {{ value_json.parameters[0].unit }}
Values: Level: {{ (value_json.parameters[0].values()|list)[3] }} 

That prints attribute values of first element in the parameters array.

Ah damned mental autocomplete, it the second value "name": "t" for temperature. Not sure what the level and leveltype is so basically it’s three values I want for each sensor. name, unit and values. Then I can use their table to customize each sensor with the correct name etc.
Actually wondering if I should give it a go and see if I can reverse engineer some other plugin like yr.no to do it for me! :smiley:

Damn you’re fast… :heart:
When I trie that in the template part of home-assistant I still get the same error that value_json is undefined?

You can try the same in the Template editor under Developer Tools… Here is the code I used.

{% set value_json = {
    "validTime": "2018-02-12T20:00:00Z",
    "parameters": [{
        "name": "msl",
        "levelType": "hmsl",
        "level": 0,
        "unit": "hPa",
        "values": [1002.5]
    },
   {
        "name": "Wsymb2",
        "levelType": "hl",
        "level": 0,
        "unit": "category",
        "values": [6]
    }]
}%}

Name: {{ value_json.parameters[0].name }}
Level Type: {{ value_json.parameters[0].levelType }}
Level: {{ value_json.parameters[0].level }}
Unit: Level: {{ value_json.parameters[0].unit }}
Values: Level: {{ (value_json.parameters[0].values()|list)[3] }} 

Ah I had forgotten to add that part at the top, Thanks! Really looks like it’s working now!

sigh feeling really stupid now… I tried adding a new sensor like this
- platform: mqtt
state_topic: “/SMHI”
name: ‘{{ value_json.parameters[1].name }}’
unit_of_measurement: ‘{{ value_json.parameters[1].unit }}’
value_template: '{{ (value_json.parameters[1].values()|list)[4] }} ’
qos: 0

and was expecting that it would create a sensor.Wsymb2 but instead of fetching the name as I thought it would I got a sensor._value_jsonparameters1name with a unknown value and unit_of_measurement: {{ value_json.parameters[1].unit }}

This nite point down the right track

Thanks, but still not sure if I can get the “name” from the json that way… The thing is that we have it working by downloading it to a txt file and then using that. But the weather service keeps changing positions so that one week temp is child nr 2 and the next week nr 12…

The problem with SMHI is that their json respons does not always keep the list the same order. So parameter[0] isnt always the same sensor.

Just had a look at the Jason file as I has a square break in it don’t think it will work :angry:

Ok so I ditched the hole idea about getting names from the json to and instead split it up in node red to each separate value… but when I try to add a sensor to my install I don’t get any values?
I’ve tried 2 different methods in the template editor in the frontend:

{% set my_test_json = {“name”:“t”,“levelType”:“hl”,“level”:2,“unit”:“Cel”,“values”:0.4} %}
The temperature is {{ my_test_json.values }} {{ my_test_json.unit }}.

but then I get a error saying: The temperature is <built-in method values of dict object at 0x67659198> Cel.

So then I tried this instead:

{% set my_test_json = {“name”:“t”,“levelType”:“hl”,“level”:2,“unit”:“Cel”,“values”:[0.4]} %}
The temperature is {{ my_test_json.values[0] }} {{ my_test_json.unit }}.

but then I don’t get any values The temperature is Cel.

This what I used to test it…

Imitate available variables:
    {% set value_json = {
        "name": "msl",
        "levelType": "hmsl",
        "level": 0,
        "unit": "hPa",
        "values": [1002.5]
    }%}

Name: {{ value_json.name }}
Level Type: {{ value_json.levelType }}
Level: {{ value_json.level }}
Unit: Level: {{ value_json.unit }}
Values: Level: {{ (value_json.values()|list)[4][0] }} 

Output…

Imitate available variables:

Name: msl
Level Type: hmsl
Level: 0
Unit: Level: hPa
Values: Level: 1002.5

1 Like