Help with json

Hello
I get messages from MQTT sensors in json format, a hint on how to extract one value, how to add a sensor to HA.
This is the message
Battery
{ “Batterymeter”: [{ “value”: 52229, “unit”, “%”}, { “value”: 3388, “unit”: “volt”}]}
wind sensor
{ “Anemometer”: [{ “value”: 0.06 “unit”, “m / s”}, { “value”: 0.22 “unit”: “km / h”}]}

I’m going to need a hint from you regarding which values you want to extract. For example, if you want the first value for Battery, the MQTT Sensor and its template would be something like this:

- platform: mqtt
  name: Battery
  state_topic: your_mqtt_topic_goes_here
  device_class: battery
  value_template: "{{ value_json.Batterymeter[0]['value'] // 1000 }}"

This template gets the first value (52229) divides it by 1000 and discards any remainder to produce 52. The sensor’s device_class is battery so the Lovelace UI will display it using a battery icon and report the value as 52%.


EDIT

You should know that both examples you provided are not in valid JSON format. The first unit should be followed by a colon (:) and not a comma (’,’)

I would believe something like:

value_template: '{{ value_json["Batterymeter"]["0"].value }}' # 52229
value_template: '{{ value_json["Batterymeter"]["1"].value }}' # 3388

value_template: '{{ value_json["Anemometer"]["0"].value }}' # 0.06
value_template: '{{ value_json["Anemometer"]["1"].value }}' # 0.22

But that is a partial guess

No, this will not work.
Use the format that @123 provided.

In your format you are missing a dot in front of “Batterymeter”. Also “Batterymeter” doesn’t need to be inside brackets and quotes. You also need to remove the quotes around 0 and 1, with quotes it will be interpreted as a string, but you need an int.

I used the format that
@123 suggested but it doesn’t work. Does not read data from the sensor.

It worked:
value_template: ‘{{value_json.batterymeter [0] .value}}’
value_template: ‘{{value_json.batterymeter [1] .value}}’
but gets 52229% and 3388v. How do I make it get 52% and 3.3v?

I don’t see any issue with @123’s suggestion.

I tested it in the Template Editor:

What’s did not work?

Edit: Double check your json payloads, as the ones you posted are not valid json, @123 pointed this out already.

1 Like

This:

{{ value_json.Batterymeter[0]['value'] }}

and this:

{{ value_json.Batterymeter[0].value }}

and even this:

{{ value_json['Batterymeter'][0]['value'] }}

are functionally equivalent and will produce the same result.

I don’t know what you did to cause it to fail but I can assure you it works. I now know what you did to make it fail. You used batterymeter in the template instead of Batterymeter. The key’s name in the received data is Batterymeter and that’s exactly how you must reference it in the template. In other words, JSON key names are case-sensitive.

The reason your result is 52229, and mine is 52, is because your template doesn’t perform integer division by 1000. If you review my previous post you’ll see I explained that part.

What is the topic you assigned to the sensor’s state_topic?

Battery Level:

value_template: "{{ value_json.batterymeter [0] .value // 1000 }}"

Voltage:

value_template: "{{ (value_json.batterymeter [1] .value / 1000) | round(1) }}"

But it’s 3.4V not 3.3V :wink:

Eh ?
Any truncated value always gives floor
I’ve always been suspicious of round() since : -
3.1415926536 | round(3) did not give me 3.142
I now add half the last required decimal and just truncate using a %3 format

Edit : And with epsilon errors it (round(3)) sometimes gives 3.14526 (weird huh?)

This setting works for me

  • platform: mqtt
    name: WS battery
    state_topic: battery
    device_class: battery
    value_template: “{{value_json.batterymeter [0] .value}}”
    unit_of_measurement: “%”

Thank you for your help.

There was a mistake, there were no dots.
{ “Batterymeter”: [{ “value”: 93.968, “unit”, “%”}, { “value”: 4.097, “unit”: “volt”}]}

image

image

Am I missing something?

That’s exactly what I thought too.
My first HA installation on a pi 3 read cpu temperature (which needs dividing by 1000 I then rounded it to 2dp this gave me (say) 45.21 degrees
A1 spot on, I was happy

I moved the installation (literally copied the config over) and my sensor now read (say) 41.1032 degrees even rounded to 2dp

My distance from home sensors (3dp) also show weird results (inconsistent)

So that’s why I now use the format option to avoid these ‘so called’ epsilon errors
Do a search on such, you will probably find my posts along with a few others

How in the world does that “work for you”?

You provided an example of the JSON data and the key name is Batterymeter not batterymeter. JSON key names are case-sensitive yet your template refers to batterymeter. Was the data you posted incorrect?

In addition, you wanted a percentage value yet your template reads the 5 digit number directly, without conversion. So that means it reports 52229%.

None of that meets your original requirements nor does it conform to the information you provided. So how can it possibly work correctly?

@123 sorry for the confusion, there is an error in the first post, unless proofreading did it during copying. She changed the first letter (b to B) and removed the dots. I get this message:
{“batterymeter”: [{“value”: 93.968, “unit”, “%”}, {“value”: 4.097, “unit”: “volt”}]}
That’s why I don’t have to divide the result by 1000.

I think first you should learn how to format your code properly, this is very important and prevents a lot of confusion.
Read here, point 11.

Sorry, more ‘off topic’ stuff but this is my template for my distance from home : -

"{{ '%.3f' | format(distance(states.device_tracker.life360_muttley)) }}"

So I get km before dp and metres after

It used to be : -

"{{ distance(states.device_tracker.life360_muttley) | round(3) }}"

Even if you ignore the epsilon errors, ( I’m at home at the moment ) so i get “0.010” from the top one and I get “0.01” from the bottom, so it’s a) aligned b) easier to read and c) avoids those epsilon errors.
And as you found, the errors are inconsistent (don’t always show) so this is my belt. braces and a bit of string

0.010 is 10 metres
0.01 is … hang on … I’ll get there in a minute … errr ! … 0.01 of a km so … 10 metres - its just easier

1 Like

That can’t be correct either because it’s invalid JSON. It contains the same mistake I identified in your first post. There should be a colon after "unit" not a comma.

I’m not sure how a copy-paste error can change capitalization and remove characters.

For future reference, please try to post accurate information and if it is wrong, correct it promptly. Otherwise it misleads the people trying to help you (and wastes their time solving the wrong problem).

Good luck.