Help Format JSON for RESTsensor

Hello team,
I have gone through all the posts I can find on JSON formatting and have not had much luck.
Here is my code:

`
-platform: rest

name: Sonnen Battery
scan_interval: 60
json_attributes:
  - M03
  - M04
  - M05
  - M38
  - M39
resource: !secret sonnen_api
value_template: '{{ sonnen_json }}'
  - platform: template
sensors:
    sonnen_currentpvpower:
      friendly_name: 'Sonnen Battery Current Solar Power Production'
      value_template: '{{ sonnen_json.M03 }}'
      unit_of_measurement: 'W'
      entity_id: sensor.sonnen_currentpvpower
    sonnen_consumption:
      friendly_name: 'Sonnen Battery Current Power Consumption'
      value_template: '{{ sonnen_json.M04 }}'
      unit_of_measurement: 'W'
    sonnen_soc:
      friendly_name: 'Sonnen Battery State of Charge'
      value_template: '{{ sonnen_json[11].M05 }}'
      unit_of_measurement: '%'
    sonnen_gridfeed:
      friendly_name: 'Sonnen Battery Current Grid Feed-In'
      value_template: '{{ (sonnen_json[21].M38 | float / 1000) | round(2) }}'
      unit_of_measurement: 'kW'
    sonnen_gridpurchase:
      friendly_name: 'Sonnen Battery Current Grid Consumption'
      value_template: '{{ (sonnen_json[22].M39 | float / 1000) | round(2) }}'
      unit_of_measurement: 'kW' 

`

I can get one device that has all the values (see screen shot) but my sensors all come back blank.
Any advice?
Here is the raw JSON output

{"C06":10,"C07":0,"C08":0,"C09":0,"C10":0,"C11":0,"C12":0,"C23":0,"C24":0,"M03":0,"M04":788,"M05":95,"M06":10,"M07":660,"M08":128,"M09":0,"M30":95,"M31":6816000,"M34":0,"M35":0,"M37":32689.15,"M38":0,"M39":684,"M40":11267.88,"M41":5806.29,"S01":160,"S07":"US-85339","S08":15,"S15":"45119","S16":"5.01 (405)","S65":8000,"S66":"son","S69":16000,"S70":"3.5","S71":"FALSE"}

Using the template editor, this format works

`
{% set sonnen_json={“C06”:10,“C07”:0,“C08”:0,“C09”:0,“C10”:0,“C11”:0,“C12”:0,“C23”:0,“C24”:0,“M03”:0,“M04”:788,“M05”:95,“M06”:10,“M07”:660,“M08”:128,“M09”:0,“M30”:95,“M31”:6816000,“M34”:0,“M35”:0,“M37”:32689.15,“M38”:0,“M39”:684,“M40”:11267.88,“M41”:5806.29,“S01”:160,“S07”:“US-85339”,“S08”:15,“S15”:“45119”,“S16”:“5.01 (405)”,“S65”:8000,“S66”:“son”,“S69”:16000,“S70”:“3.5”,“S71”:“FALSE”}%}

    value_template: '{{ sonnen_json}}'
  - platform: template
    sensors:
      sonnen_currentpvpower:
        friendly_name: 'Sonnen Battery Current Solar Power Production'
        value_template: '{{ sonnen_json.M03 }}'
        unit_of_measurement: 'W'
        entity_id: sensor.sonnen_currentpvpower

`
But that gives me blank sensors in the UI.
Any ideas or help?
Thanks!
sonnen

First, the value_template you’re using in the config for Sonnen Battery doesn’t make sense. There is no such thing as sonnen_json. The value_template option is used to set the state of the resulting sensor entity. What do you want the state string to be? Are there any of the values from the raw JSON that you want to be the state? E.g., if you want S71, then:

value_template: "{{ value_json.S71 }}"

If you don’t care, you could just make it:

value_template: NA

Next the resulting sensor’s entity_id will be sensor.sonnen_battery. This is what you should reference in your template sensors. E.g.:

value_template: "(( state_attr('sensor.sonnen_battery', 'M03') }}"
1 Like

Thank you for your reply @pnbruckner
I followed your guidance and understand what you are trying to explain. thank you. However your suggestion for sensor states did not have the desired effect. Code and screen shots attached.
Can i ask some educational questions I could not find documented anywhere?
How do you know the sensor’s ID will be

sensor.sonnen_battery

I don’t see sonnen_battery defiend anywhere, unless it is coming from the name: Sonnen Battery and just being parsed into a single field.
And why is the sensor

value_template: “(( state_attr(‘sensor.sonnen_battery’, ‘M04’) }}”
Instad of
value_template: “{{ state_attr(‘sensor.sonnen_battery’, ‘M04’) }}”

Anyway, I may be closer, but if you see the screen shot, not the desired effect. I posted updated code if you are willing to help.

  - platform: rest
    name: Sonnen Battery
    scan_interval: 60
    json_attributes:
      - M03
      - M04
      - M05
      - M38
      - M39
    resource: !secret sonnen_url
    value_template: '{{ value_json.M05 }}'
  - platform: template
    sensors:
        sonnen_currentpvpower:
          friendly_name: 'Sonnen Battery Current Solar Power Production'
          value_template: "(( state_attr('sensor.sonnen_battery', 'M03') }}"
          unit_of_measurement: 'W'
          entity_id: sensor.sonnen_currentpvpower
        sonnen_consumption:
          friendly_name: 'Sonnen Battery Current Power Consumption'
          value_template: "(( state_attr('sensor.sonnen_battery', 'M04') }}"
          unit_of_measurement: 'W'
          entity_id: sensor.sonnen_consumption
        sonnen_soc:
          friendly_name: 'Sonnen Battery State of Charge'
          value_template: "(( state_attr('sensor.sonnen_battery', 'M05') }}"
          unit_of_measurement: '%'
          entity_id: sensor.sonnen_soc
        sonnen_gridfeed:
          friendly_name: 'Sonnen Battery Current Grid Feed-In'
          value_template: "(( state_attr('sensor.sonnen_battery', 'M38' | float / 1000) | round(2) }}"
          unit_of_measurement: 'kW'
          entity_id: sensor.sonnen_gridfeed
        sonnen_gridpurchase:
          friendly_name: 'Sonnen Battery Current Grid Consumption'
          value_template: "(( state_attr('sensor.sonnen_battery', 'M39' | float / 1000) | round(2) }}"
          unit_of_measurement: 'kW'
          entity_id: sensor.sonnen_gridpurchase

sonnen2

Yes, it is coming from the name. It is derived by passing the name through a “slugify” function. (Not sure where the word “slugify” came from.) Basically everything is converted to lower case. Spaces are changed to underscores. And there are some other conversions that take place in some situations. E.g., if the resulting entity_id already exists, I think it will add a numeric suffix. Basically, after you add it to your configuration, restart HA and look in the States page to see what it is named. :slight_smile:

That’s a typo. It should indeed start with {{. Once you fix that (in all template sensors) it should work.

1 Like

Thank you again for the great information! when I fix the “typo” I get this new wonderful error: /home/homeassistant/.homeassistant/configuration.yaml: mapping values are not allowed here
in “/home/homeassistant/.homeassistant/configuration.yaml”, line 109, column 14

Here is the code in my config starting with line 107:

value_template: '{{ json_value.M05 }}'
  - platform: template
      sensors:      
        sonnen_currentpvpower:
          friendly_name: 'Sonnen Battery Current Solar Power Production'
          value_template: '{{ state_attr('sensor.sonnen_battery', 'M03') }}'
          unit_of_measurement: 'W'
          entity_id: sensor.sonnen_currentpvpower

If i remove the block, the config check comes back good. I will go through my config with a fine tooth comb, but if you happen to have an idea where to look I will welcome the advice!

Well, you managed to have several formatting and usage issues in those few lines! :wink:

First, for a template sensor, sensors: has to line up with platform:. Next you’re using quoting incorrectly in the value_template line. Lastly, you’re using the entity_id parameter incorrectly (which you don’t actually need to use here.)

Try:

  - platform: template
    sensors:      
      sonnen_currentpvpower:
        friendly_name: 'Sonnen Battery Current Solar Power Production'
        value_template: "{{ state_attr('sensor.sonnen_battery', 'M03') }}"
        unit_of_measurement: 'W'
1 Like

Yup! it was all formatting. I got it fixed just as you posted the reply. Thank you again for all your help!

@pnbruckner Since you have been so helpful, I have to make one other request (no good deed goes unpunished :wink: ) Would you be able to point me somewhere that shows how to convert numberical values to text?

Such as if the json returns the value of 10 - i can have it displayed as “Grid is offline” in the Home Assistant page instead of the value 10?
Cheers!

lol! No problem.

The easiest way would be to use a dictionary.

But first, are you actually using a number, or a number that has already been converted to a string? E.g., if you’re using state_attr('sensor.sonnen_battery', 'M03'), according to the original JSON you posted, that would return a number. But if you’re using states('sensor.sonnen_currentpvpower'), that, like all entity states, would be a string (even if it looks like a number.) It’s an important point when you’re going to use the value as a key to a dictionary. Of course, we could use the int filter to convert to a number, just in case. :slight_smile:

So, the basic idea is something like this:

{% set map = {10: 'Grid is offline', 9: 'Grid is below the stairs'} %}
{{ map.get(states('sensor.sonnen_currentpvpower')|int, 'Heck if I know!') }}

This is using both Jinja and Python. The first line creates a Python dictionary. The second line uses the dictionary’s get method to find the value associated with a given key, and returns the specified string if the key isn’t found. The key used for the lookup is the state of the specified entity, converted to an int.

Let me know if you have any questions.