Integrate XML data in state and esp. attributes?

Hi,

I have a XML-output, e.g.

<e2servicelist>
  <e2service>
    <e2servicereference>N/A</e2servicereference>
    <e2servicename>N/A</e2servicename>
  </e2service>
</e2servicelist>

and searched and read a lot of threads, but was not able to find the fitting solution for me:

Unfortunately the header is send as application/xhtml+xml. I think, that it is not converted to JSON because of this.

If load it via

  - platform: rest
    resource: 'http://IP/web/subservices'

the value is

<?xml version="1.0" encoding="UTF-8"?><e2servicelist>	<e2service>		<e2servicereference>N/A</e2servicereference>		<e2servicename>N/A</e2servicename>	</e2service>	</e2servicelist>

Is there any way to get this to work, so I take the data e.g. via

  - platform: rest
    resource: 'http:/IP/web/subservices'
    value_template: '{{ value_json["e2servicereference"] }}'
    json_attributes:
      - e2servicename

esp. to have one value as state and the other as attribute.

If I get it currently as

  - platform: command_line
    command: 'curl get "http://IP/web/subservices" 2>&1 | grep -oPm1 "(?<=<e2servicereference>)[^<]+"'

It is working, but is there a way to select two values and put one in the state and the other in an attribute?

If I get/tried this currently via

  - platform: scrape
    resource: 'http:/IP/web/subservices'
    select: 'e2servicereference'

it is working as well, but here the same question with both values, one as state and the other als attribute. And scrape (or - hopefully not - all ways) leave the last state, if e.g. http:/IP/web/subservices is offline. But in this case, I want a 404 or whatever state and not the last successful one. Is this only via scrape and/or hat to customize the behavior?

Thanks a lot in advance, for some hints and information. :slight_smile:

Update for those, who want to know the same thing after further tests:

  • rest-sensor updates the sensor state with “not available” :white_check_mark:
  • command_line-sensor-curl does not update the sensore state if not available and leaves the last state :x:
  • scrape-sensor same as command_line_curl :x:

Any way to change the bevavior of command_line-curl and/or scrape to update as 404, not available, … as rest is doing?

And any idea to get rest working in my example, if the other ones do not update the status (if service not available)?

Update: It was/is because of missing application/xhtml+xml. I added this locally in sensor.py and it is now working.

Update: Created a pull request, which is already merged now.

But still the questions:

  • how to manage that command_line and scrape are updating with unknown, 404, timeout or whatever instead of leaving the old state value?

  • is it really not possible to store multiple values as attributes from different paths of one json/xml instead of only within one single json_attributes_path?

Hello,

I’m trying to integrate MSI Afterburner Server info into a rest sensor.
XML value is as below but Home Assistant is not able to conver to JSON even after i update to 2021.1

<HardwareMonitor>
<HardwareMonitorHeader>
<signature>1296123981</signature>
<version>131072</version>
<headerSize>32</headerSize>
<entryCount>14</entryCount>
<entrySize>1324</entrySize>
<time>1610025698</time>
<gpuEntryCount>1</gpuEntryCount>
<gpuEntrySize>1304</gpuEntrySize>
</HardwareMonitorHeader>
<HardwareMonitorEntries>
<HardwareMonitorEntry>
<srcName>GPU temperature</srcName>
<srcUnits>C</srcUnits>
<localizedSrcName>GPU temperature</localizedSrcName>
<localizedSrcUnits>C</localizedSrcUnits>
<recommendedFormat>%.0f</recommendedFormat>
<data>55</data>
<minLimit>0</minLimit>
<maxLimit>100</maxLimit>
<flags>None</flags>
<gpu>0</gpu>
<srcId>0</srcId>
</HardwareMonitorEntry>
<HardwareMonitorEntry>
<srcName>Power</srcName>
<srcUnits>%</srcUnits>
<localizedSrcName>Power</localizedSrcName>
<localizedSrcUnits>%</localizedSrcUnits>
<recommendedFormat>%.0f</recommendedFormat>
<data>54</data>
<minLimit>0</minLimit>
<maxLimit>150</maxLimit>
<flags>None</flags>
<gpu>0</gpu>
<srcId>96</srcId>
</HardwareMonitorEntry>
</HardwareMonitorEntries>
<HardwareMonitorGpuEntries>
<HardwareMonitorGpuEntry>
<gpuId>VEN_10DE&DEV_2484&SUBSYS_261719DA&REV_A1&BUS_43&DEV_0&FN_0</gpuId>
<family>GA104-A</family>
<device>GeForce RTX 3070</device>
<driver>460.89</driver>
<BIOS>94.04.25.40.db</BIOS>
<memAmount>0</memAmount>
</HardwareMonitorGpuEntry>
</HardwareMonitorGpuEntries>
</HardwareMonitor>

Here is my config but it’s not working (HA is throwing an error):

  - platform: rest
    resource: http://192.168.10.8:82/mahm
    username: MSIAfterburner
    password: my_password
    json_attributes_path: "$..*"
    json_attributes:
      - hardwaremonitor
    value_template: 'OK'

The error is

REST result could not be parsed as JSON

The page header is like below

image

Is this the whole response header? I’m not able to see the response content-type comparing to my example:

image

And with this, HA trys to transform to JSON, if it is “text/xml”, “application/xml” or “application/xhtml+xml”.

Yes, that is what i get in Chrome Developer tool.

Does it mean that the response header is not including content-type therefore Hass can’t trigger Json convertion?

Yes, this is how it is currently working. But perhaps you can get it via scrape or command_line-curl. See examples above.

1 Like

Ok, thanks for your help.
I ended up using scrap sensor. It is not my prefered solution as i can’t have the value in attributes to create dynamic sensors but at least it’s working.

sensor:
  - platform: scrape
    name: GPU Temp
    resource: http://192.168.10.8:82/mahm
    username: MSIAfterburner
    password: my_password
    select: "HardwareMonitorEntry:nth-of-type(1) data"
    unit_of_measurement: "C"

  - platform: scrape
    name: GPU Power
    resource: http://192.168.10.8:82/mahm
    username: MSIAfterburner
    password: my_password
    select: "HardwareMonitorEntry:nth-of-type(2) data"
    unit_of_measurement: "%"