XML page TO database INFLUXDB

Hello everybody.

I started using node-red recently and I discovered that it is a very powerful application with which infinite automations can be created. I searched in this forum but without success, an example or suggestions to read the data of an XML page of an address http://192.168.2.8/bcc.xml and copy them in the INFLUXDB database to finally create graphs (GRAFANA) for the monitoring of my photovoltaic system (battery cell charger, panel production, etc.).

With my little experience in NODE-RED I was able to transform the XML page data into objects (arrays) or into a data string. I believe they need a JSON script to select only the single values and copy them into the INFLUXDB database.

Thanks in advance to those who could give me a little suggestion and help, thanks
Regards

this is the XML page

this is the incorrect result of the influxd database with the wrong value field

You can put this in a function node to move the values into msg.payload.

// move msg.payload.data into msg.payload
msg.payload = msg.payload.data
// take first element of the array in each entry
for (const [key, value] of Object.entries(msg.payload)) {
    msg.payload[key] = value[0]
}
return msg;

However I don't think that is enough. Presumably you want all the numeric fields as Number type rather than string. Also what do you want to do with the N/A values?

Dear Mr. Colin, I often read your precious interventions and help and for this I thank you.
All N / A values are numbers that correspond to the voltage reading of the individual cells that make up the battery.

I am attaching an example of the XML format in which only fields are already filled in

or if it can be of help and interest to other people for reading the photovoltaic data, this is the manual: GWL/MODULAR Battery Communicator and Controller

Thank you and have a good weekend

So what do you want to do with those fields when you write them to influx? Possibly you want to leave them empty.

Also which fields do you want to convert to numbers and which leave as strings? You have to think about each field and decide what you want to put into influx. For example the relay1 and relay2 fields are strings, but do you want to set those to 0 and 1 so you can plot them on a graph (for instance) or do you want to leave them as strings? What about status?

Once you know what you want to do with each field then it can be coded up.

Colin, you are a kind person who took my request for help to heart.

To simplify, I have decoded the type of fields in the INFLUXDB database which will be subsequently displayed by GRAFANA.
All N / A fields need to be converted to numbers.
The "connection" field must be string while the "relay1" and "relay2" fields will be set to 0 or 1 to plot a graph.

Best regards

<utotal> NUMBER </utotal>
<ucell1> NUMBER</ucell1>
<ucell2> NUMBER </ucell2>
<ucell3> NUMBER </ucell3>
<ucell4> NUMBER </ucell4>
<ucell5> NUMBER </ucell5>
<ucell6> NUMBER </ucell6>
<ucell7> NUMBER </ucell7>
<ucell8> NUMBER </ucell8>
<ucell9> NUMBER </ucell9>
<ucell10> NUMBER </ucell10>
<ucell11> NUMBER </ucell11>
<ucell12> NUMBER </ucell12>
<ucell13> NUMBER </ucell13>
<ucell14> NUMBER </ucell14>
<ucell15> NUMBER </ucell15>
<ucell16> NUMBER </ucell16>
<trimmer-0> NUMBER </trimmer-0>
<trimmer-1> NUMBER </trimmer-1>
<UMINset> NUMBER </UMINset>
<UMAXset> NUMBER </UMAXset>
<Umincell> NUMBER </Umincell>
<Umaxcell> NUMBER </Umaxcell>
<UmincellID> NUMBER </UmincellID>
<UmaxcellID> NUMBER </UmaxcellID>
<Udiff> NUMBER </Udiff>
<lastcellevent> NUMBER </lastcellevent>
<lastcellno> NUMBER </lastcellno>
<lastcellU> NUMBER </lastcellU>
<lastbattU> NUMBER </lastbattU>
<connection> STRING </connection>
<status> NUMBER </status>
<relay1> 1 OR 0 </relay1>
<relay2> 1 OR 0</relay2>

What number for fields that are in the xml as N/A? Would it not be better to leave them as null in the database if they show N/A in the xml?

Assuming that what you want is for them to be left empty then this might do it. Make sure you check it out in a debug node before connecting to the influx node.

const data = msg.payload.data
msg.payload = {}
// take first element of the array in each entry
for (const [key, value] of Object.entries(data)) {
    if (key === "connection") {
        msg.payload[key] = value[0]
    } else if (value[0] != "N/A") {
        msg.payload[key] = Number(value[0])
    } else {
        // leave field empty if N/A
    }
}
return msg;

Colin, we're almost there :slight_smile:
The "function" object works perfectly in fact it displays the values of the fields correctly in the debug.
Influxdb object displays error 400 "unable to parse".

The value of the two relays does not work because the NaN value remains unchanged even if I try to change the state

Where am I doing wrong?

influxdb

The relays are not working because I forgot to handle them. Your original debug does not have lastcelevent, lastcellu or lastbattu. What is in them in the xml?
What are the two string values for the relays that need to be converted to 1 and 0?

Dear Colin,

  • the values of the lines of the two relays is NORMAL or SWITCHED;
  • the values of lastcellU and "lastbattU" are numeric;
  • the value of "lastcellevent" is a string.

if a good person, thank you

Best regards,
Ilario DP

Show me the xml in a debug node for an example including the last... values.

You have not said which is 0 and which is 1 for the relays.

The status of the value 0 or 1 of the relays is indifferent.
Attached is the screeshot of the card and some examples on how it works.

relè-d

relè-c

relè-b

So lastcellU and lastbattU have a V on the end. Did you not see the NaN numbers and look back at the xml to see why they were different? Similarly had you looked at the lastcellevent value you would have seen it was a string, which would have saved us both some time.

Try this

const data = msg.payload.data
msg.payload = {}
// take first element of the array in each entry
for (const [key, value] of Object.entries(data)) {
    if (key === "connection" ||  key === "lastcellevent") {
        msg.payload[key] = value[0]
    } else if (key.startsWith("relay")) {
        msg.payload[key] = value[0] === "SWITCHED"  ?  1  :  0
    } else if (value[0] != "N/A") {
        msg.payload[key] = parseFloat(value[0])
    } else {
        // leave field empty if N/A
    }
}
return msg;

If you still have any incorrect values then make sure to post the xml as well as the function output.

!!! WOW !!!

Dear Colin, I'm sorry I wasted your time.
Your invaluable support was very important that you gave me a happy weekend. If you come to Italy in Rome I will be happy to offer you a coffee.

Thank you again.
Ilario DP

Glad to be of help. Now spend some time working out how the function works so that next time you will be able to sort it yourself. :slight_smile:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.