Can we see the actual XML? When people make up replacement data, we often end up chasing a problem in the source data we can’t see. For example, if any of the keys in the real data starts with a digit, then you need bracket notation:
{{ value_json['blubb']['3rd_zone'] }}
and if any of the values are non-numeric, you cannot specify unit_of_measurement or state_class.
How? Do you see the sensor but it is unknown? Do you not see the sensor at all (and if so, have you restarted HA to load up the rest integration?)?
Also some XML → json puts an @ in front of the key, but I can’t remember the rule. Which was Why I wanted to see the converted data with {{value}}.
I did not get that there are additional logs hidden in the settings. I thought the “logbook” (translated) in the main menu would be all the logs I get.
Now the real logs are something I can work with. Thank you for hinting me to that.
So with the original yaml of the original post i get:
Template variable error: 'value_json' is undefined when rendering '{{ value_json.blubb.zone3 }}'
Seems to me that the file can not be parsed to json. I would also be fine with XQuery/XPath that is usually used for xml data, but this seems to be not available in homeassistant. At least I could not find anything about that in the docs.
When i use value_template: "{{ value }}" i get this error:
ValueError: Sensor sensor.nameOfSensor has device class 'None', state class 'measurement' unit 'Amount' and suggested precision 'None' thus indicating it has a numeric value; however, it has the non-numeric value: '<?xml version="1.0"?>
<blubb>
<foo/>
<bar/>
<zone1>496</zone1>
<zone2>231</zone2>
<zone3>528</zone3>
</blubb>' (<class 'str'>)
2024-02-06 14:20:39.682 ERROR (MainThread) [homeassistant.components.sensor] Error while setting up rest platform for sensor
Traceback (most recent call last):
File "/lsiopy/lib/python3.11/site-packages/homeassistant/components/sensor/__init__.py", line 644, in state
numerical_value = float(value) # type:ignore[arg-type]
^^^^^^^^^^^^
ValueError: could not convert string to float: '<?xml version="1.0"?>\n<blubb>\n <foo/>\n <bar/>\n <zone1>496</zone1>\n <zone2>231</zone2>\n <zone3>528</zone3>\n</blubb>'
So at least the data is there.
I would rather not to be honest. But im promise that the data looks exactly like that. No digits in the xml elements. No special characters either. Data is always numerical.
I also tried some variants of the JSONPath that would work in an online evaluator, but without any luck.
Seems not to be the case here. There goes something wrong in the conversion from XML → JSON.
What does this mean? The “sensor” in this case is an online API.
So there’s nothing wrong with the configuration as you have presented it. My guess is that it’s something in your headers, or an oddity like an invisible Byte Order Mark, or (despite your protestations to the contrary) something in the real data that is throwing it. Try tom_l’s suggestion — if the XML you’re reading is over 255 characters, use {{ value[:250] }} as the template.
Thank you for going far beond what can be expected to test this.
Could you also add the xml header and try again? Maybe this is what makes the jjson parser to hickup?
My test above fails if I rename the file to end in .php, as my web server sends it with different headers.
value in that situation is the full XML but value_json is undefined, just as you’re seeing: because of the headers, HA doesn’t run the conversion.
You will either need to get your PHP script / server to send as text/xml if you want to use HA’s XML-to-JSON conversion (the correct solution); or you will have to botch it by manually scraping the XML, something like this:
Following a DM with the OP, it turns out that the real server in question will respond with application/xml if the request ends in .xml rather than .php. So this:
[homeassistant.helpers.template] Template variable warning: 'value_json' is undefined when rendering '{{ value_json }}'
What do you mean with “results”. I then cann search the sensor on the “overview” tab of the webinterface. And there i can see its value. Is there a better way doing this?
Thank you for testing even further and finding out what the problem was.
Could this be considered a bug, or is this behavour expected?
Since I am not in control over the API I am not able to change the header unfortunately. But i am happy with some regex magic.
It is now workign as expected. Big thank you to both of you for your time!
One last slightly off topic question:
I have set this unique id in the sensor …
unique_id: "this.isaverylong.unique.name"
… but in the webinterface the entitiy-id shows up as sensor.name. Am I doing something wrong here, or do i get the concept wrong?
It could be considered a bug in the source server that it sends out XML with the wrong headers. HA behaviour is expected.
The latter. The sensor entity ID comes from the name by default, so:
sensor:
- name: "Blubb Zone 3"
would be sensor.blubb_zone_3. The unique_id is an internal thing, needed for allowing customisation and assigning to areas. You can rename the entity ID in the UI later if you want, but best not to.