Help with JSON between brackets

I searched and found a few threads but none of them really made a difference, I tried several different ways of setting up the rest sensor but none of them work. Can someone please help? I tried to read how to form the syntax but I fail every time.

I have an energy monitor hooked up to a raspi, and I’m using a software that will output the following, I’m trying to create a sensor to output the “watt” bit, which is how many watts are currently going through my electricity meter so I can monitor the electricity usage in real time. How can I make this “watt” value into a sensor (value shown as 549 on the pasted text)?

Please note this is the raw output from the software and I cannot change the way it is, home assistant keeps telling me “JSON is not a dictionary”.

[{"sensor":{"sensor_id":"0","sensor_title":"Electricity","sensor_clamp":"0","position_id":"3","position_time":"2019-09-20 17:50:46","position_description":"Usage","position_sensor":"0","measure_history":"3650","measure_currency":"Pound","measure_sensor":"0","measure_range":"0","measure_timeframe":"0","measure_timezone":"GMT0","measure_timezone_diff":"0","measure_type":"0","measure_pvoutput_id":"","measure_pvoutput_api":"","measure_scale_factor":"1.00","measure_lower_limit":"0","positions":{"3":{"position":"3","time":"2019-09-20 17:50:46","description":"Usage"}}},"tmpr":"15.7","watt":"549","daily":"12.673 Kwh<br \/>1.8","hourly":"0.374 Kwh<br \/>0.05","weekly":"85.42 Kwh<br \/>12.14","monthly":"312.969 Kwh<br \/>44.47"}] 

This is how the sensor is currently set up, and I already tried value_json.watt[0] which yields the same error:

  - platform: rest
    json_attributes:
      - watt
    resource: "http://SERVER_URL/php/measureit_functions.php?do=summa$
    name: "Power Use Now"
    value_template: '{{ value_json.sensor }}'
    unit_of_measurement: Watts
    device_class: power 

Paste this into the Template Editor and observe the result of the template (which is located at the very end). The result will be 549.

{% set value_json = [{
	"sensor": {
		"sensor_id": "0",
		"sensor_title": "Electricity",
		"sensor_clamp": "0",
		"position_id": "3",
		"position_time": "2019-09-20 17:50:46",
		"position_description": "Usage",
		"position_sensor": "0",
		"measure_history": "3650",
		"measure_currency": "Pound",
		"measure_sensor": "0",
		"measure_range": "0",
		"measure_timeframe": "0",
		"measure_timezone": "GMT0",
		"measure_timezone_diff": "0",
		"measure_type": "0",
		"measure_pvoutput_id": "",
		"measure_pvoutput_api": "",
		"measure_scale_factor": "1.00",
		"measure_lower_limit": "0",
		"positions": {
			"3": {
				"position": "3",
				"time": "2019-09-20 17:50:46",
				"description": "Usage"
			}
		}
	},
	"tmpr": "15.7",
	"watt": "549",
	"daily": "12.673 Kwh<br \/>1.8",
	"hourly": "0.374 Kwh<br \/>0.05",
	"weekly": "85.42 Kwh<br \/>12.14",
	"monthly": "312.969 Kwh<br \/>44.47"
}] %}

{{ value_json[0].watt }}

Experiment with it to get a feel for how to extract values.

Now here’s the bad news, the RESTful Sensor’s json_attributes option is incapable of handling the data you have. For starters, it’s a list containing a dictionary and json_attributes cannot parse the list.

2 Likes

Thank you for responding so quickly, this is the first time I will be using this template editor. I pasted the above and I can see the watt value, I can see that you used {{ value_json[0].watt }} to extract it right at the end.

The data is dynamic and will be changing every second or so, it’s coming from an URL, I’m not sure how to use this template stuff, and since you said that the restful sensor cannot parse it, do you have any suggestion of something else I could use?

I integrated and customized my homeassistant quite a bit, I just don’t know how to deal with this one and have been stuck for weeks, so I finally threw in the towel and created a forum account to get help :’-(

This is a not so elegant brute force solution that might work. Just parse the result as a string in the template. This will fail if there is another occurrence of “watt” in your result and it assumes that the returned value is quoted, i.e. “549” and not 549:

  - platform: rest
    resource: "http://SERVER_URL/php/measureit_functions.php?do=summa$
    name: "Power Use Now"
    value_template: '{{value.split("watt\":\"")[1].split("\"")[0]}}'
    unit_of_measurement: Watts
    device_class: power 

A better solution might be a simple python script that converts the result to json and then parses the result.

1 Like

This is built-in functionality now, there’s a template filter as of v0.101 called from_json that converts a JSON string to an object from which you can access arbitrary fields.

value_template: '{{ (value | from_json)[0].watt }}'

There is also to_json if you ever need that.

3 Likes

Yes, continue to use the RESTful Sensor but change the template. Use regex_findall_index to extract the desired value.

  - platform: rest
    resource: "http://SERVER_URL/php/measureit_functions.php?do=summa$
    name: "Power Use Now"
    value_template: >
      {{ value | regex_findall_index("watt\": \"(\d+)\"") }}
    unit_of_measurement: Watts
    device_class: power 

There’s a pattern-matching language called ‘regular expression’ or simply ‘regex’. The pattern I’m using is this:

watt\": \"(\d+)\"

This regex pattern means:

  • Match the literal string watt
  • Match a literal double-quote. However, a double-quote has special meaning in regex so we have escape its meaning by prepending a backslash to the double quote \"
  • Match a literal colon and space
  • Match another double-quote
  • Match one or more digits \d+
  • The parentheses surrounding (\d+) mean the matching digits should be captured (it’s called a ‘capture group’).
  • Match one more double-quote

If it finds text matching this pattern then it returns the capture group, which is the value of watts.

If you want to learn more, I recommend you go to regex101.com and use its online regex tester. Just paste the supplied pattern into the top field and your data in the bottom field.

2 Likes

I tested this solution and for my use case, it works perfectly! Thank you!

Another solution tested, and it also works perfectly, I like the simplicity of the expression. I appreciate you taking your time to reply.

I appreciate all the answers the other gave me but yours has gone a step further, it shows me a little about regex (I was so confused) and provides a source for me to research further. I appreciate the extra bits of info. Unfortunately when I use your expression homeassistant won’t create the sensor for some reason. But thank you very much for taking a lot of your time to pass on further info which will be valuable to me and others in the future.

Sorry to hear that. I had created an MQTT version of the same sensor (because I can send data to it for it testing purposes) to confirm the template works.

  - platform: mqtt
    name: "test"
    state_topic: "test/sensor"
    value_template: >
      {{ value | regex_findall_index("watt\": \"(\d+)\"") }}
    unit_of_measurement: Watts
    device_class: power 

After restarting Home Assistant, the sensor was present and, after I published your data to the topic test/sensor, the sensor received it and the template extracted 549

Screenshot%20from%202019-11-01%2001-30-34

Screenshot%20from%202019-11-01%2001-29-59

I don’t know why it isn’t even creating the sensor for you. We could investigate (by checking the logs for error messages) or just ignore it because Steve’s solution is simpler and more elegant. You have him to thank for adding the from_json filter to the latest version of Home Assistant.

1 Like

If you want me to provide logs I am more than happy to do so, although now that it’s working I would think your time could be best used helping someone else around the forum who still has an issue, trying not to be greedy and selfish here :slight_smile:

1 Like