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
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
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
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
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?
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.
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.