Restful sensor with XML response

Cheers Everybody !!! )

I’m trying define restful sensor which indicates state of dimmer for front panel display of my Denon x4500 AV receiver.

I’ve followed to description at: https://www.home-assistant.io/integrations/rest/ and defined it as following:

sensor:
  - platform: rest
    name: Front Display
    resource: https://<ip_of_my_denon>:10443/ajax/general/get_config?type=10
    verify_ssl: false
    json_attributes_path: "$.FrontDisplay"
    scan_interval: 120
    value_template: 'OK'
    json_attributes:
      - "Dimmer"

which assumes that XML should be converted to JSON and then I define that actual response is located at “FrontDisplay” and define json attribute as Dimmer.

Actual response is as following:

<?xml version="1.0" encoding="utf-8"?>
<FrontDisplay><Dimmer>1</Dimmer><Channel display="3">2</Channel></FrontDisplay>

And here is what home assistant reposts to me:
2020-11-27 22:26:20 WARNING (MainThread) [homeassistant.components.rest.sensor] REST result could not be parsed as JSON

I use Home Assistant 0.118.0.dev0. Any ideas are welcome and appreciated! )

ok here is what ha debug logging shows:

2020-11-28 01:24:22 DEBUG (MainThread) [httpx._client] HTTP Request: GET https://<ip>:10443/ajax/general/get_config?type=10 "HTTP/1.1 200 OK"

2020-11-28 01:24:22 DEBUG (MainThread) [homeassistant.components.rest.sensor] Data fetched from resource: <?xml version="1.0" encoding="utf-8"?>

<FrontDisplay><Dimmer>1</Dimmer><Channel display="3">2</Channel></FrontDisplay>

2020-11-28 01:24:22 WARNING (MainThread) [homeassistant.components.rest.sensor] REST result could not be parsed as JSON

2020-11-28 01:24:22 DEBUG (MainThread) [homeassistant.components.rest.sensor] Erroneous JSON: <?xml version="1.0" encoding="utf-8"?>

<FrontDisplay><Dimmer>1</Dimmer><Channel display="3">2</Channel></FrontDisplay>

2020-11-28 01:24:22 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=sensor.front_display, old_state=None, new_state=<state sensor.front_display=<?xml version="1.0" encoding="utf-8"?>

<FrontDisplay><Dimmer>1</Dimmer><Channel display="3">2</Channel></FrontDisplay>; friendly_name=Front Display @ 2020-11-28T01:24:22.900279+02:00>>

also important to note that response has content type: “application/x-javascript”, so no automatic detection that data is XML.

Is there a way to specify explicitly that response data is XML? Regardless what buggy denon reports…

Did you ever figure this out? I am having the same problem with an endpoint that is returning Content-Type: text/html but it is actually XML.

Me to :frowning:

I’m trying to get the status from my Roth Touchline heating system.
It’s already integrated using the Touchline integration, but that one dosen’t pull the system-status.

The request is:

curl -H "Content-Type: text/xml" -d "<body><item_list><i><n>R0.SystemStatus</n></i></item_list></body>" http://<IP-of-controller>/cgi-bin/ILRReadValues.cgi

and the response is:

< HTTP/1.1 200 OK
< Server: Keil-EWEB/2.1
< Content-Type: text/html
< Cache-Control: no-cache
< Connection: close
<
* Closing connection 0
<body><item_list><i><n>R0.SystemStatus</n><v>0</v></i></item_list></body>

So yes XML with wrong content type.
No chance I will get Roth to fix this, and since it looks to be a fairly common problem, a simple configuration variable “content type” or “response format” seems to be appreciated.

/Morten

1 Like

Hi’ Morten.

Don’t know if you ever got this to work ?
Anyway, I’ve made a crude ‘bruteforce xml’ solution.
It’s not pretty, but it works :laughing:

command_line:
  - sensor:
      name: Touchline status
      command: 'curl -H "Content-Type: text/xml, User-Agent: Roth-Touchline.../1.05" -d "<body><item_list><i><n>R0.SystemStatus</n></i></item_list></body>" http://XXX.XXX.X.X/cgi-bin/ILRReadValues.cgi'
      scan_interval: 60
      value_template: '{{ value | regex_findall_index("<v>(\d*)</v>") }}'

Sorry should have reported back here.
Got some help, I think in the danish HA facebook group, and came up with this:

# Get status from Roth Touchline
##sensor:
- platform: rest
  name: Roth Touchline status
  resource: "http://192.168.0.20/cgi-bin/ILRReadValues.cgi"
  scan_interval: 300
  method: POST
  payload: '<body><item_list><i><n>R0.SystemStatus</n></i></item_list></body>'
  headers:
      Content-Type: application/xml
    #- name: "touchline_SystemStatus"
  value_template: "{% set value = value.replace('</v>','<v>').split('<v>') %}{{ value[1]|int }}"

So actually using the restful sensor but handling the XML output manually.
Think you value_template is a bit more clean though :slight_smile:

No worries :sunglasses:
Better with two possible public solutions than none.

As a sidenote I can tell that if you have sensors on both a master and a slave controller, missing temperature sensors (error 3) will be shown via device #0 only. I actually expected that issues with sensors connected to the slave device would be reported via device #1.

I’ve made a custom component out of my Touchline integration and added the three missing heat modes (Pro1 Night, Pro2 Night and Pro3 Night). Tested and working here locally. Details can be found in reported Github issue here

I’m currently trying to figure out how to change state from heat to idle by calculation using current temperature and target temperature. As the actual valve state is not in the registers, one can only assume that state in theory should be heat when current temperature is below target temperature.
This won’t apply though for sensors running in night mode (default -3 degress from target) and/or multiple sensors pr. valve (average temperature used).

Python is not really my strong side (I’m just a tinkerer, not a dev) so it will be an uphill sprint and I’m not sure I’ll succeed on my own. So any help would be appreciated :grin:

Absolutely :slight_smile:

Wow that’s a bit confusing with the slave controller. Fortunately I have exactly 12 zones, so can still get by with just one controller.

Didn’t actually noticed the missing modes, probably because I have the heating pipes in the concrete floor, so temperature changes is way to slow to care about night saving.

I have tried this alternative integration:

using mqtt.

He is recording the temperature changes from the thermostats, and a thermostats has not changed temperature in 24 hours, it’s reported as unavailable.
Cleaver.
But I never managed to make a propper add-on out of it, so I dropped it.

Sorry my python skills are also very limited, actually my programming skills are generally not very impressing, so can’t help you much there.

But nice work so far :+1: