Converting JSON Data to CSV

Incoming MQTT data is often JSON formatted data and in order to extract data values from it.

Storing the data directly as JSON formatted data is also common

However it is also very common to store this data as CSV or a least convert it to CSV for use in legacy systems.



With node-red this is very easy to do with the csv node

csv-node-icon

Which you will find in the parser group of modes.

The CSV node will concert an incoming JavaScript Object into a CSV string or an incoming CSV string into a JavaScript Object.

The settings for the node are shown below:

csv-node-settings

JSON to CSV

An incoming JSON string will first need to be converted into a JavaScript object using the JSON node.

This will be the case when reading data from a file.

However when injecting using the inject node or getting JSON data from an MQTT node then the data is already a JavaScript object.

The JSON data is in key:value pairs and you will need to use the key names for the columns.

As an example the following incoming JSON data:

{
    “time”: 1650644910938,
    “pressure”: 9.77,
    “temp”: 70.14,
    “battery”: 3.29
}
would require the column settings
time,pressure,temp,battery

Flat vs Nested JSON data

The csv node only works however for flat JSON data if we have nested data like that below:

{
    “time”: 1650644910938,
    “data”: {
        “pressure”: 9.77,
        “temp”: 70.14,
        “battery”: 3.29
    }
}
Then it doesn’t work.
To make it work we first need to flatten the JSON object using a function node with the following code:
function flattenObject(ob) {
    var toReturn = {};

    for (var i in ob) {
        if (!ob.hasOwnProperty(i)) continue;

        if ((typeof ob[i]) == 'object' && ob[i] !== null) {
            var flatObject = flattenObject(ob[i]);
            for (var x in flatObject) {
                if (!flatObject.hasOwnProperty(x)) continue;

                toReturn[i + '.' + x] = flatObject[x];
            }
        } else {
            toReturn[i] = ob[i];
        }
    }
    return toReturn;
}
msg.payload = flattenObject(msg.payload);
return msg;

Note: I didn’t write the code above .I can’t remember if I got it from a forum or chatGPT. I have made it into a subflow to make it easier to use.

If we inject the nested data show previously into the function node we get the following output:

flatten-object-output

Notice that instead of the keys pressure,temp,battery we have data.pressure,data.temp,data.battery.

So now we just need too edit the CSV node to look like the following:

csv-node-example-1

The video and flow from the video doesn’t include this function node an updated demo flow is below:

Video



Related Tutorials and Resources

Click to rate this post!
[Total: 2 Average: 5]

Leave a Reply

Your email address will not be published. Required fields are marked *