0

I would like to read data from my solar inverter and post it to pvoutput.org. The inverter answers this xml:

<Device Name="StecaGrid 4200" Type="Inverter" Serial="********************" BusAddress="1" NetBiosName="***************" IpAddress="***.***.****.***" DateTime="2020-01-18T16:31:31">
<Measurements>
<Measurement Value="225.492" Unit="V" Type="AC_Voltage"/>
<Measurement Value="0.442" Unit="A" Type="AC_Current"/>
<Measurement Value="83.860" Unit="W" Type="AC_Power"/>
<Measurement Value="49.983" Unit="Hz" Type="AC_Frequency"/>
<Measurement Value="470.400" Unit="V" Type="DC_Voltage"/>
<Measurement Value="0.182" Unit="A" Type="DC_Current"/>
<Measurement Value="85.840" Unit="W" Type="DC_Power"/>
<Measurement Value="20.000" Unit="°C" Type="Temp"/>
</Measurements>
</Device>
</root> 

I use the following code to read the data:

import urllib.request, urllib.parse, urllib.error
import xml.etree.ElementTree as ET

url = 'http://***.***.***.***/measurements.xml'

uh = urllib.request.urlopen(url)
data = uh.read()

tree = ET.fromstring(data)

lst = tree.findall('Measurements')

counts = tree.findall('.//Measurement')
print(tree.findall('.//Measurement').find('AC_Voltage'))

for each in counts:
    print(each.attrib['Type'], each.attrib['Value'], each.attrib['Unit'])

If there is sunshine, the results look like this:

C_Voltage 226.632 V
AC_Current 0.259 A
AC_Power 41.920 W
AC_Frequency 49.980 Hz
DC_Voltage 451.896 V
DC_Current 0.100 A
DC_Power 45.270 W
Temp 18.100 °C

But when a value is 0, the attribute is omitted.

Only if AC_Power >0, I want to upload the data. How can I store these attributes in variables or arrays in order to create a POST url?

1 Answer 1

1

better parsers like "lxml" of the beautifulsoup4 can Ease the job. assuming the polling to the inverter happens at fixed intervals and you get data periodically in xml file you might want to install lxml and beautiful soup first with following combined command :

python3 -m pip install lxml bs4 beautifulsoup4

now whatever xml you have with any attributes and child tags, you can do the following method by using beautifulsoup4 to get the value of the attribute.

from bs4 import BeautifulSoup as soup
import requests
import lxml

def read_ac_power(file_name):
    data=open(file_name, 'r').read()
    variabul=soup(data,'lxml')
    val=variabul.findAll('measurement')[2]
    return val['value']

AC_Power=float(read_ac_power('inverter'))
print(AC_Power)

#compare the variable and send to server , use POST [or your preferred] method

If you dont want to store file remove the open(file_name, 'r').read() method and directly plugin your data.

Explanation

the essence is float() which explicitly converts the string of xml doc to float.

val=variabul.findAll('measurement')[2]  #AC_power is stored as 3rd item...

return val['value'] #returns a string & need conversion
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.