Need help for pasing a xml file

Hi,

i try to read values from my pv inverter (Kostal Piko MP) via XML. The file looks like this:

<root>
<Device Name="PIKO 3.0-1 MP plus" Type="Inverter" Platform="Net16" HmiPlatform="HMI17" NominalPower="3000" UserPowerLimit="nan" CountryPowerLimit="nan" Serial="767682GJ008177530020" OEMSerial="10351314" BusAddress="1" NetBiosName="INV008177530020" WebPortal="PIKO Solar Portal" ManufacturerURL="kostal-solar-electric.com" IpAddress="192.168.50.11" DateTime="2021-12-12T11:13:39" MilliSeconds="750">
<Measurements>
<Measurement Value="232.7" Unit="V" Type="AC_Voltage"/>
<Measurement Value="0.464" Unit="A" Type="AC_Current"/>
<Measurement Value="104.5" Unit="W" Type="AC_Power"/>
<Measurement Value="107.2" Unit="W" Type="AC_Power_fast"/>
<Measurement Value="49.992" Unit="Hz" Type="AC_Frequency"/>
<Measurement Value="279.5" Unit="V" Type="DC_Voltage"/>
<Measurement Value="0.412" Unit="A" Type="DC_Current"/>
<Measurement Value="339.8" Unit="V" Type="LINK_Voltage"/>
<Measurement Unit="W" Type="GridPower"/>
<Measurement Unit="W" Type="GridConsumedPower"/>
<Measurement Unit="W" Type="GridInjectedPower"/>
<Measurement Unit="W" Type="OwnConsumedPower"/>
<Measurement Value="100.0" Unit="%" Type="Derating"/>
</Measurements>
</Device>
</root>

So, due to a bad formatting its not that easy and i’m struggeling to read the values with the rest sensor. The only line i need would be the “Type=“AC_POWER”” one. If i would get all, and have different sensors, it would be also okay.

Could someone help me to parse that output?

Thanks.

value_template: "{{ value_json.Device.Measurements[2]["@Value"] }}"

To do this I pasted your XML here: https://www.freeformatter.com/xml-to-json-converter.html, converted to json and pasted the result in the left hand box here: https://jsonpathfinder.com/, then drilled down to your wanted measurement on the right. The path is shown at the top of the right hand column. Just replace x with value_json.

Thanks! That helped much.

Unfortunately I get an error message

Template variable error: 'dict object' has no attribute 'Device' when rendering '{{ value_json.Device.Measurements[3]['@Value'] }}'

My sensor looks like this

- platform: rest
  resource: http://IP/measurements.xml
  name: "pv_wr_pi_solar"
  value_template: "{{ value_json.Device.Measurements[3]['@Value'] }}"
  device_class: power
  unit_of_measurement: W

Try this:

- platform: rest
  resource: http://IP/measurements.xml
  name: "pv_wr_pi_solar"
  value_template: "{{ value_json['@Device']['@Measurements'][3]['@Value'] }}"
  device_class: power
  unit_of_measurement: W

Thanks. Error message is now gone.

But I don’t get any values in my sensor. I put a scan_interval: 10 in it, but still no values after some time. No other error message in the log.

I wonder if we can get the actual xml → json conversion in an attribute (it will be bigger than the 255 chars allowed for states). What do the attributes of this look like:

- platform: rest
  resource: http://IP/measurements.xml
  name: "pv_wr_pi_solar"
  value_template: "{{ 'OK' }}"
  json_attributes_path: "$"
  json_attributes:
    - "Device"

Or maybe:

- platform: rest
  resource: http://IP/measurements.xml
  name: "pv_wr_pi_solar"
  value_template: "{{ 'OK' }}"
  json_attributes_path: "$"
  json_attributes:
    - "@Device"

I don’t get any attributes but a warning in the log

2021-12-12 13:55:08 WARNING (MainThread) [homeassistant.components.rest.sensor] JSON result was not a dictionary or list with 0th element a dictionary
2021-12-12 13:55:08 WARNING (MainThread) [homeassistant.components.rest.sensor] JSON result was not a dictionary or list with 0th element a dictionary

Hallo, did you solve this somehow plz? I have similar issue with reading multiple values from one XML file, cant get it working, inly with multiple REST sensors - what seems to repeatedly read the XML and this leads to timeouts / not available results …

My XML code looks like this:

- <meas>
- <I1>
  <P>-0.11</P> 
  </I1>
- <I2>
  <P>-0.04</P> 
  </I2>
- <I3>
  <P>-0.32</P> 
  </I3>
- <I4>
  <P>34.1</P> 
  <E>0.00</E> 
  </I4>
- <I5>
  <P>40.0</P> 
  <E>0.00</E> 
  </I5>
- <I6>
  <P>46.7</P> 
  <E>0.00</E> 
  </I6>
- <I7>
  <P>0.00</P> 
  <E>4896.60</E> 
  </I7>
- <O1>
  <A>0</A> 
  <P>0.00</P> 
  <E>0.00</E> 
  <HN>0</HN> 
  <HC>0</HC> 
  <HE>0</HE> 
  <HR>0</HR> 
  <T>0</T> 
  <TOT>0</TOT> 
  <TFT>0</TFT> 
  <TT>0</TT> 
  <ER>0</ER> 
  </O1>
- <O2>
  <A>0</A> 
  <P>0.00</P> 
  <E>0.00</E> 
  <HN>0</HN> 
  <HC>0</HC> 
  <HE>0</HE> 
  <HR>0</HR> 
  <T>0</T> 
  <TOT>0</TOT> 
  <TFT>0</TFT> 
  <TT>0</TT> 
  <ER>0</ER> 
  </O2>
- <O3>
  <A>0</A> 
  <P>0.00</P> 
  <E>0.00</E> 
  <HN>0</HN> 
  <HC>0</HC> 
  <HE>0</HE> 
  <HR>0</HR> 
  <T>0</T> 
  <TOT>0</TOT> 
  <TFT>0</TFT> 
  <TT>0</TT> 
  <ER>0</ER> 
  </O3>

and the config.yaml
I am trying this:

# Výkon/Odběr na fázi 1
  - platform: rest
    name: wr_1
    resource: !secret Watt_IP
    json_attributes_path: "$.meas.I1"
    value_template: "OK"
    json_attributes:
      - "P"
    verify_ssl: false
    timeout: 20
    force_update: true
    scan_interval: '00:05:00'
  - platform: template
    sensors:
      vykon_f1:
        friendly_name: "Výkon/Odběr L1"
        value_template: "{{ state_attr('sensor.wr_1', 'P') }}"
        unit_of_measurement: "kW"
  
# Výkon/Odběr na fázi 2
  - platform: rest
    name: wr_2
    resource: !secret Watt_IP
    json_attributes_path: "$.meas.I2"
    value_template: "OK"
    json_attributes:
      - "P"
    verify_ssl: false
    timeout: 20
    force_update: true
    scan_interval: '00:05:00'
  - platform: template
    sensors:
      vykon_f2:
        friendly_name: "Výkon/Odběr L2"
        value_template: "{{ state_attr('sensor.wr_2', 'P') }}"
        unit_of_measurement: "kW"

# Výkon/Odběr na fázi 3
  - platform: rest
    name: wr_3
    resource: !secret Watt_IP
    json_attributes_path: "$.meas.I3"
    value_template: "OK"
    json_attributes:
      - "P"
    verify_ssl: false
    timeout: 20
    force_update: true
    scan_interval: '00:05:00'
  - platform: template
    sensors:
      vykon_f3:
        friendly_name: "Výkon/Odběr L3"
        value_template: "{{ state_attr('sensor.wr_3', 'P') }}"
        unit_of_measurement: "kW"

the problem is that there are more values stored in one file and I need to read them all repeatedly, and if I read more than 10 values, the system is probably reading XML file from server 10 times and gets laggy and timeouts appear…
is there a way to read the XML file e.g. only once and then parse it into several values at one time?

this exact sample is for WattRouter XML (meas.xml file) where are stored power values (power, cuurent, voltage etc.) of my solar power plant per each phase (phase 1, 2 and 3)

help please anubody :slight_smile: thx.

Use the new rest integration, not the legacy rest sensor platform. The integration can update as many sensors as you want from the one call to the resource.

Thanks for advice, I was using restful before, but wasn’t able to address different nests in the XML,
for instance I need to read all P values and some E values and put them in different variables.
(like Power, Volts, Amps etc…)

  • finally I got it working last week with Multiscrape HACS integration, so it is finally OK.

if someone is nterrested, here is the code:

multiscrape:
  - resource: !secret Watt_IP
    scan_interval: 300
    sensor:
      - unique_id: vykon_f1
        name: "Výkon/Odběr L1"
        select: "meas > I1 > P"
        unit_of_measurement: "kW"
      - unique_id: vykon_f2
        name: "Výkon/Odběr L2"
        select: "meas > I2 > P"
        unit_of_measurement: "kW"
etc...

2 Likes

Now I need st. similar, but for JSON source file :slight_smile: (another list of different sensors, but generated by API form my SIEMENS RVS21 controll board (using it for Thermal pump heating and DHW preparation).
The API gets laggy when trying to read more than 15 values. Since the API response takes appros 1-2 secs. and if I put more than 15 vars I receive tomeouts,
So far I only partially succeded with different refresh times (scan_intervals set differently) to gain more time to read all vars… but this is only temporary solution, I need to learn how to address different nests in JSON response from API menu tree, where are all vars listed in one longer gerenrated subpage…

Response:
{
  "MenuItems":
    [
  
    ],
  "DatapointItems":
    [
  
    {
      "Id": "2469",
      "Address": "0x5009a",
      "DpSubKey": "0",
      "WriteAccess": "false",
      "Text": {
        "CatId": "2",
        "GroupId": "2",
        "Id": "19",
        "Long": "Chybové hlášení",
        "Short": "Chybové hlášení"
      }  
  },
  
  
    {
      "Id": "2470",
      "Address": "0x5009a",
      "DpSubKey": "6",
      "WriteAccess": "false",
      "Text": {
        "CatId": "2",
        "GroupId": "2",
        "Id": "19",
        "Long": "Chybové hlášení",
        "Short": "Chybové hlášení"
      }  
  },
  
  
    {
      "Id": "2471",
      "Address": "0x5009c",
      "DpSubKey": "0",
      "WriteAccess": "false",
      "Text": {
        "CatId": "2",
        "GroupId": "2",
        "Id": "2217",
        "Long": "Servisní hlášení",
        "Short": "Servisní hlášení"
      }  
  },
  
  
    {
      "Id": "2472",
      "Address": "0x5009c",
      "DpSubKey": "2",
      "WriteAccess": "false",
      "Text": {
        "CatId": "2",
        "GroupId": "2",
        "Id": "11",
        "Long": "Adresa LPB",
        "Short": "Adresa LPB"
      }  
  },
  
  
    {
      "Id": "2473",
      "Address": "0x5009c",
      "DpSubKey": "5",
      "WriteAccess": "false",
      "Text": {
        "CatId": "2",
        "GroupId": "2",
        "Id": "2217",
        "Long": "Servisní hlášení",
        "Short": "Servisní hlášení"
      }  
  },
  
  
    {
      "Id": "2474",
      "Address": "0x5009c",
      "DpSubKey": "7",
      "WriteAccess": "false",
      "Text": {
        "CatId": "2",
        "GroupId": "2",
        "Id": "11",
        "Long": "Adresa LPB",
        "Short": "Adresa LPB"
      }  
  },
  
  
    {
      "Id": "2475",
      "Address": "0x500a0",
      "DpSubKey": "0",
      "WriteAccess": "false",
      "Text": {
        "CatId": "2",
        "GroupId": "2",
        "Id": "7175",
        "Long": "Event message",
        "Short": "Event message"
      }  
  },
  
  
    {
      "Id": "2476",
      "Address": "0x2d067d",
      "DpSubKey": "0",
      "WriteAccess": "false",
      "Text": {
        "CatId": "2",
        "GroupId": "2",
        "Id": "2587",
        "Long": "Žádaná teplota náběhu vysoušení TO1",
        "Short": "ŽádTeplNábVysouš 1"
      }  
  },
  

Hallo mr Berka.
Can you send me pls full yaml about yor wattrouter ? I so have wattrouter ,and yours looks great.
Prosím o poslaní vašeho yaml ohledně wattrouteru. Máte to moc hezky zpracované ,pomohlo by mi to. .-)
Děkuji Jiří

Hi Christian

did you find out how to read the values of the Kostal Piko.
i have now the same situation, and i m thinking about whats the best way to get the values from my Piko MP.

No sorry. I run node-red extra for that. But know I want to get rid of node-red but unfortunately I cannot get the sensor to run.

Hallo / Ahoj, the full code in YAML for WattRouter so far looks like this:

  - resource: !secret Watt_IP_meas
    scan_interval: 300
    sensor:
      - unique_id: vykon_f1
        name: "Výkon/Odběr L1"
        select: "meas > I1 > P"
        unit_of_measurement: "kW"
      - unique_id: vykon_f2
        name: "Výkon/Odběr L2"
        select: "meas > I2 > P"
        unit_of_measurement: "kW"
      - unique_id: vykon_f3
        name: "Výkon/Odběr L3"
        select: "meas > I3 > P"
        unit_of_measurement: "kW"
      - unique_id: teplota_aku_d
        name: "Teplota AKU-D"
        select: "meas > I4 > P"
        unit_of_measurement: "°C"
      - unique_id: teplota_aku_h
        name: "Teplota AKU-H"
        select: "meas > I5 > P"
        unit_of_measurement: "°C"
      - unique_id: teplota_tuv
        name: "Teplota TUV"
        select: "meas > I6 > P"
        unit_of_measurement: "°C"
      - unique_id: vykon_fve_maneler
        name: "Měřený výkon FVE"
        select: "meas > I7 > P"
        unit_of_measurement: "kW"
      - unique_id: celkova_vyroba_fve
        name: "Výroba FVE od spuštění"
        select: "meas > I7 > E"
        unit_of_measurement: "kWh"

Some hours of struggling with the examples i found a working solution for the Kostal Piko MP Plus:

sensor:
  - platform: rest
    resource: http://IPAdress_for_the_Inverter/measurements.xml
    name: "Piko MP AC Power"
    value_template: "{{ value_json.root.Device.Measurements.Measurement[2]['_Value']}}"
    device_class: power
    unit_of_measurement: W

At the moment it seems to work fine for me.

Hi all, I have just started with Home Assistant and want to integrate our Heat Pump Controller. It has a xml webpage below but how do I get the values to show?

sorry a real newbie

"?xml version="1.0" encoding="windows-1250" ?>
<?xml-stylesheet type="text/xsl" href="HOME.XSL?U=1588753443" version="1.0" ?>
<PAGE TITLE="                                  ">
<ACCESS PAGE_LEVEL="0" USER_LEVEL="0" UCID="1588753443" />
<INPUT NAME="__R3189_TIME_Thh:mm:ss" VALUE="02:00:00" />
<INPUT NAME="__R37954_TIME_Thh:mm:ss" VALUE="00:10:00" />
<INPUT NAME="__R4008.0_BOOL_i" VALUE="1" />
<INPUT NAME="__R79565.0_BOOL_i" VALUE="0" />
<INPUT NAME="__R79565.1_BOOL_i" VALUE="0" />
<INPUT NAME="__R3159.0_BOOL_i" VALUE="0" />
<INPUT NAME="__R79564.6_BOOL_i" VALUE="0" />
<INPUT NAME="__R79564.7_BOOL_i" VALUE="0" />
<INPUT NAME="__R37958.1_BOOL_i" VALUE="1" />
<INPUT NAME="__R24863.0_BOOL_i" VALUE="1" />
<INPUT NAME="__R5439.1_BOOL_i" VALUE="1" />
<INPUT NAME="__R2357.1_BOOL_i" VALUE="1" />
<INPUT NAME="__R22657_REAL_.1f" VALUE="18.5" />
<INPUT NAME="__R22661_REAL_.1f" VALUE="0.0" />
</PAGE>"

I have tried this

  • platform: rest
    resource: http://192.168.14.232/EN/HOME.XML
    authentication: basic
    username: user
    password: 1Desmonddo
    name: “pv_wr_pi_solar”
    value_template: “{{ _R22657_REAL.1f[3][’@Value’] }}”
    device_class: temperature
    unit_of_measurement: C

I put it in the /config/configuration.yaml but that did not work.

On my PIKO 3.0-2 MP plus I see that all the data comes from HTTP://inverter-ip/measurements.xml

So I installed GitHub - danieldotnl/ha-multiscrape: Home Assistant custom component for scraping (html, xml or json) multiple values (from a single HTTP request) with a separate sensor/attribute for each value. Support for (login) form-submit functionality.

And used the following configuration to get the data. Added this to configuration.yaml


# Kostal inverter    
multiscrape:
  - resource: http://192.168.0.90/measurements.xml
    scan_interval: 60
    parser: lxml
    sensor:
      - unique_id: kostal_ac_power
        name: "AC Power"
        select: "measurement[type='AC_Power']"
        attribute: "value"
        unit_of_measurement: "W"
        on_error:
          value: "default"
          default: 0.0
      - unique_id: kostal_ac_voltage
        name: "AC Voltage"
        select: "measurement[type='AC_Voltage']"
        attribute: "value"
        unit_of_measurement: "V"
        on_error:
          value: "default"
          default: 0.0
      - unique_id: kostal_ac_current
        name: "AC Current"
        select: "measurement[type='AC_Current']"
        attribute: "value"
        unit_of_measurement: "A"
        on_error:
          value: "default"
          default: 0.0        
      - unique_id: kostal_ac_frequency
        name: "AC Frequency"
        select: "measurement[type='AC_Frequency']"
        attribute: "value"
        unit_of_measurement: "Hz"
      - unique_id: kostal_dc_voltage
        name: "DC Voltage"
        select: "measurement[type='DC_Voltage']"
        attribute: "value"
        unit_of_measurement: "V"
        on_error:
          value: "default"
          default: 0.0
      - unique_id: kostal_dc_current
        name: "DC Current"
        select: "measurement[type='DC_Current']"
        attribute: "value"
        unit_of_measurement: "A"
        on_error:
          value: "default"
          default: 0.0
      - unique_id: kostal_link_voltage
        name: "Link Voltage"
        select: "measurement[type='LINK_Voltage']"
        attribute: "value"
        unit_of_measurement: "V"
        on_error:
          value: "default"
          default: 0.0
      - unique_id: kostal_derating
        name: "Derating"
        select: "measurement[type='Derating']"
        attribute: "value"
        unit_of_measurement: "%"
1 Like

I know this thread topic is become a bit old but just hoping someone can help me on a similar problem.

I am trying to pull just the humidity value from the following XML data generated by my local sensor:

<server host="Watchdog Peach" address="192.168.1.52" name="Watchdog 15" product-version="1.6.0" mac-address="D8:80:39:23:E8:5B" datetime="2023-05-28 12:27:36" company="Geist" company-url="http://www.geistglobal.com" support-email="[email protected]" support-phone="800.432.3219 / +1.402.474.3400 " console-id="bb015" tempunit="F" poe-option="0" driver="OwAAV100"> <devices> <device id="37D8803923E85BC3" name="Watchdog Peach" type="BB-TH" available="1" index="0"> <field key="Temp" value="79.45" niceName="Temperature"/> <field key="Humidity" value="54" niceName="Humidity"/> <field key="Dewpt" value="61.35" niceName="Dewpoint"/> </device> </devices> <alarms> </alarms> <cameras> </cameras> </server>

I think I have successfully converted to json using the xml to json (previously referenced) converter and then pasted into the json path finder (previously referenced). I have setup and tried numerous variants of the rest integration in my yaml files as follows:

  • platform: rest
    resource: http://192.168.1.52/data.xml
    name: Geist Humidity
    value_template: “{{ value_json[devices.device.field[1][’@value’]] }}”
    scan_interval: 30

But in every case, I am not seeing any payload out (using Node Red to debug node):

image

Any suggestions would be greatly appreciated,
Thank you.

Here is a screenshot of my XML since I’m not sure if it is showing up above.