RESTful and XML Integration

I have now updated to 0.107 and it works perfect :slight_smile:

Thanks a lot!

2 Likes

I have a similar question, and try to readout an xml file.
Does anyone know how to apply the resolution in this topic on my xml file?

<root>

<Device Name="StecaGrid 3010" Type="Inverter" Platform="HSSNet11" HmiPlatform="HMI13" NominalPower="3000" UserPowerLimit="nan" CountryPowerLimit="nan" Serial="748609ZD005345830026" OEMSerial="" BusAddress="1" NetBiosName="INV005345830026" WebPortal="Steca sunCloud" ManufacturerURL="www.steca.com" IpAddress="192.168.1.26" DateTime="2021-05-03T09:09:13">

<Measurements>

<Measurement Value="234.5" Unit="V" Type="AC_Voltage"/>

<Measurement Value="2.703" Unit="A" Type="AC_Current"/>

<Measurement Value="618.6" Unit="W" Type="AC_Power"/>


</Measurements>

</Device>

</root>

I need this value:

<Measurement Value="618.6" Unit="W" Type="AC_Power"/>

Thanks

Try this as a starting point.

value_json['root']['Device']['Measurements']['Measurement'][?(@['@Type']=='AC_Power')]['@Value']

If that doesn’t work, I’d recommend using the link in the first post to convert your XML into JSON, and then use a JSON Path evaluator to play around with the path until it works. And hopefully that will then also work in HA.

1 Like

Thanks for your answer, still some issues with the syntax:

'{{ value_json["root"]["Device"]["Measurements"]["Measurement"][?(@["@Type"]=="AC_Power")]["@Value"] }}'. (
Invalid config for [sensor.rest]: invalid template (TemplateSyntaxError: unexpected char '?' at 63) for dictionary value @ data['value_template']. Got '{{ value_json["root"]["Device"]["Measurements"]["Measurement"][?(@["@Type"]=="AC_Power")]["@Value"] }}'. (See ?, line ?).

Maybe I do something wrong :slight_smile:

There is a chance that the filter syntax using a question mark is not supported here, or may need to be encoded somehow…?

Alternatively, here is a less pretty version that iterates through the remaining array:

{% for x in value_json["root"]["Device"]["Measurements"]["Measurement"] -%}
{% if x["@Type"] == "AC_Power" %}{{x["@Value"]}}{% endif %}
{%- endfor %}
1 Like

How Genius, it works!!!
Thank you !!

Now i can see solar production in real time!

1 Like

Can the value template also be modified if there is no response (at night this ip doesn’t respond). That the value will be 0?

Not sure how exactly the sensor handles this case, but you could try surrounding the above template with an if-expression like this:

{% if value_json is defined %}
... insert template from above...
{% else %}
0
{% endif %}

If the ip does not respond, you will get an error from rest adapter as well in the log. I don’t like this and would like to get a round this error with a clause in the sensor or whatever as well.

Any way to have this without filtering in logger settings, because this is not a special or unique error message to filter.

Maybe by changing the logger component in home assistant?

logger:
  default: info
  logs:
    homeassistant.components.rest.sensor: info

As I said: Any way to have this without filtering in logger settings, because this is not a special or unique error message to filter.

Of course, I want to have still errors for this component or this sensor, but not if this sensor is not available.

Should be possible to round that @Value retrieved?

Thanks

Maybe with the round option?

{{x["@Value"]} | round(1) }

where you can change 1 as needed.

I got it!,

Just in case:

This is the correct format:

{{x[“@Value”] | round(1) }}

Hi,

Do you have an idea to read out this code:

var myChart;var chartData =
{
"labels":
[
"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"],
"datasets":
[
{
"strokeColor": style_strokecolor,
"fillColor": style_fillcolor,
"data": [
8.017000,13.462000,12.060000,18.398000,16.043000,11.227000,12.979000,14.212000,10.465000,11.991000,15.286000,17.721000,0.000000,0.000000,0.000000,
0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,
0.000000]
}
]
}
var max = 25;
var steps = 5;
var input = document.getElementById("inputId");
input.setAttribute("min",   "2020-09");
input.setAttribute("max",   "2021-08");
input.setAttribute("value", "2021-08");
document.getElementById("labelValueId").innerHTML = " 161.867kWh 08.2021";
document.getElementById("buttonPrevId").disabled  = false;
document.getElementById("buttonNextId").disabled  = true;
window.onresize = function(event) { myChart.resize();  }
myChart = new Chart(document.getElementById("canvasId")
.getContext("2d"))
.Bar(chartData,
{
"pointDot": false,
"datasetFill": false,
"scaleOverride": true,
"scaleLabel": "<%=value%> kWh",
"scaleSteps": steps,
"scaleStartValue": 0,
"scaleStepWidth": Math.ceil(max / steps),
"scaleLineColor": style_linecolor,"scaleFontColor":  style_fontcolor,"responsive": true});

labels are the day’s of the month.
and data is the amount of KWH my solar produces that day.
I need a sensor that gets the amount of the current date.

It’s a Java JS file on my solar inverter (gen.yield.month.chart.js).

any info would me great!

I don’t think there is any suitable integration that you could use to parse this JavaScript code.

The way I would approach this is as follows:

  • Develop a simple custom component that fetches this JavaScript file. (May this code here can give you some inspiration, but instead of binary_sensor you want to implement a sensor.)
  • Find the content of the chartData variable.
  • Parse its content as JSON, find today’s value and populate a sensor/entity with the right meta-data.

Hello,
I own an eta pellet unit and was able to use this instructions to setup rest sensors for temperature, pressure and even the status and the amount of pellets. Now I wanted to setup the switches of the pellet unit too. I’ve to make POST requests application/x-www-form-urlencoded and submit ‘value’: 1803 for on
and ‘value’: 1802 for off.
For the status of the switch I got the following XML answer to my GET request:

<eta xmlns="http://www.eta.co.at/rest/v1" version="1.0">
<value uri="/user/var/120/10101/0/0/12080" strValue="Aus" unit="" decPlaces="0" scaleFactor="1" advTextOffset="1802">1802</value>
</eta>

or

<eta xmlns="http://www.eta.co.at/rest/v1" version="1.0">
<value uri="/user/var/120/10101/0/0/12080" strValue="Ein" unit="" decPlaces="0" scaleFactor="1" advTextOffset="1802">1803</value>
</eta>

in node red I used a function node for the body of the post request, it works, but I want to transfer it to the rest or the command line switch.

Function Node:

msg.headers={ 
    'Content-Type': 'application/x-www-form-urlencoded'
};
msg.payload = {};
msg.payload={ 
    'value': 1803
};
return msg;

I tried the following switches:

Rest switch:

  - platform: rest
    resource: http://192.168.1.128:8080/user/var/40/10021/0/0/12080
    name: Heizkessel Switch ETA
    method: post
    body_on: '{"value": 1803}'
    body_off: '{"value": 1802}'
    is_on_template: '{{ value_json == body_on }}'
    headers:
      Content-Type: application/x-www-form-urlencoded

or

  - platform: command_line
    switches:
      test_heizkessel:
        command_on: 'curl -X POST -H ‘Content-Type: application/x-www-form-urlencoded’ -d ‘{“value”:"1803"}’ http://192.168.1.128:8080/user/var/40/10021/0/0/12080”'
        command_off: 'curl -X POST -H ‘Content-Type: application/x-www-form-urlencoded’ -d ‘{“value”:"1802"}’ http://192.168.1.128:8080/user/var/40/10021/0/0/12080”'
        command_state: "/usr/bin/curl -X GET http://192.168.1.128:8080/user/var/40/10021/0/0/12080"

both without success. Can anybody help me with this?

Thanks Daniel

According to your node-red code, the payloads should be

    body_on: "'value': 1803"
    body_off: "'value': 1802"

without curly braces

@koying thanks for your help, but this doesn’t work either. The switch doesn’t move. I also tried to change the is_on_template to get the real state by using the value_template of the according sensor

is_on_template: '{{ value_json["eta"]["value"]["@strValue"] == "Ein" }}'

Any other suggestions?

@Daniel76

Hi! I had the similar problem of how to control my ETA heating and I got it to work with a command line switch:

switch:
- platform: command_line
  switches:
    eta_kessel:
      command_on: >
        /usr/bin/curl -X POST -d 'value=1803' -H "Content-Type: application/x-www-form-urlencoded" "http://192.168.0.1:8080/user/var//40/10021/0/0/12080"
      command_off: >
        /usr/bin/curl -X POST -d 'value=1802' -H "Content-Type: application/x-www-form-urlencoded" "http://192.168.0.1:8080/user/var//40/10021/0/0/12080"
      command_state: /usr/bin/curl -X GET "http://192.168.0.1:8080/user/var//40/10021/0/0/12080"
      value_template: '{{ value | regex_findall("strValue=\"([a-zA-Z]+)\"", ignorecase=TRUE) | first == "Ein" }}'
      friendly_name: ETA Kessel
    eta_heizung:
      command_on: >
        /usr/bin/curl -X POST -d 'value=1803' -H "Content-Type: application/x-www-form-urlencoded" "http://192.168.0.1:8080/user/var//120/10101/0/0/12080"
      command_off: >
        /usr/bin/curl -X POST -d 'value=1802' -H "Content-Type: application/x-www-form-urlencoded" "http://192.168.0.1:8080/user/var//120/10101/0/0/12080"
      command_state: /usr/bin/curl -X GET "http://192.168.0.1:8080/user/var//120/10101/0/0/12080"
      value_template: '{{ value | regex_findall("strValue=\"([a-zA-Z]+)\"", ignorecase=TRUE) | first == "Ein" }}'
      friendly_name: ETA Heizung

This solution still produces some warning but seems to work nevertheless.

WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: 'TRUE' is undefined when rendering '{{ value | regex_findall("strValue=\"([a-zA-Z]+)\"", ignorecase=TRUE) | first == "Ein" }}'

So while that is not a solution with RESTful, it shows how to brute force an xml. It is not elegant at all but I am glad it finally works! :partying_face:

1 Like