How to split a long message and filter for information

Hi,
I'm quite new in working with node red. I got this following message from a Victron Batterie Monitor (BMV 712) and I would like to get some of the data in an InfluxDB.
I use the node VE.direct USB triggered by a timestamp and parse it with the json node.
How can I convert this data in something the InfluxDB can work with?

{
"PID": {
"value": "0xA383",
"description": "ProductID",
"units": "",
"product": "BMV-712 Smart Rev2"
},
"V": {
"value": 26479,
"description": "Main or channel 1 (battery) voltage",
"units": "mV"
},
"T": {
"value": 20,
"description": "Battery temperature",
"units": "°C"
},
"I": {
"value": 0,
"description": "Main or channel 1 battery current",
"units": "mA"
},
"P": {
"value": 0,
"description": "Instantaneous power",
"units": "W"
},
"CE": {
"value": -1305,
"description": "Consumed Amp Hours",
"units": "mAh"
},
"SOC": {
"value": 998,
"description": "State-of-charge",
"units": "‰"
},
"TTG": {
"value": -1,
"description": "Time-to-go",
"units": "Minutes"
},
"Alarm": {
"value": "OFF",
"description": "Alarm condit…

Thanks a lot in advance.

Welcome to the forum @Emmi

Do you know exactly what form you want the data in?

If not then which version of influxdb are you using and do you know what measurements, fields and tags you want?

Hi,
thanks for the fast response. I use InfluxDB v2.8.0. Looks like I copied the wrong output (I tried a lot before asking you)
This is what the json node gives me:

{"PID":{"value":"0xA383","description":"ProductID","units":"","product":"BMV-712 Smart Rev2"},"V":{"value":27517,"description":"Main or channel 1 (battery) voltage","units":"mV"},"T":{"value":23,"description":"Battery temperature","units":"°C"},"I":{"value":-181,"description":"Main or channel 1 battery current","units":"mA"},"P":{"value":-5,"description":"Instantaneous power","units":"W"},"CE":{"value":-6171,"description":"Consumed Amp Hours","units":"mAh"},"SOC":{"value":994,"description":"State-of-charge","units":"‰"},"TTG":{"value":14400,"description":"Time-to-go","units":"Minutes"},"Alarm":{"value":"OFF","description":"Alarm condition active","units":""},"Relay":{"value":"OFF","description":"Relay state","units":""},"AR":{"value":0,"description":"Alarm reason","units":""},"BMV":{"value":712,"description":"Model description (deprecated)","units":""},"FW":{"value":419,"description":"Firmware version (16 bit)","units":""},"MON":{"value":0,"description":"DC monitor mode","units":""},"H...

First I would like to have the basic values: Voltage, Temperature, Current
and the status of the Alarm also would be nice.

This is a suggestion I got from ChatGPT for some JavaScript in function node to process your JSON before sending it to an InfluxDB node. I'm assuming your message is in msg.payload

let d = msg.payload;

msg.payload = {
    measurement: "bmv712",

    tags: {
        PID: d.PID.value,
        product: d.PID.product
    },

    fields: {
        V_mV: d.V.value,
        T_C: d.T.value,
        I_mA: d.I.value,
        P_W: d.P.value,
        CE_mAh: d.CE.value,
        SOC_permille: d.SOC.value,
        TTG_min: d.TTG.value,

        Alarm: d.Alarm.value,
        Relay: d.Relay.value,

        AR: d.AR.value,
        BMV: d.BMV.value,
        FW: d.FW.value,
        MON: d.MON.value
    }
};

return msg;

You can edit/delete the 'fields' as necessary.

What do you see before the JSON node?

msg.payload : Object

object

PID: object

value: "0xA383"

description: "ProductID"

units: ""

product: "BMV-712 Smart Rev2"

V: object

value: 26500

description: "Main or channel 1 (battery) voltage"

units: "mV"

T: object

value: 21

description: "Battery temperature"

units: "°C"

I: object

value: 207

description: "Main or channel 1 battery current"

units: "mA"

P: object

value: 5

description: "Instantaneous power"

units: "W"

CE: object

value: -1424

description: "Consumed Amp Hours"

units: "mAh"

SOC: object

value: 997

description: "State-of-charge"

units: "‰"

TTG: object

value: -1

description: "Time-to-go"

units: "Minutes"

Alarm: object

value: "OFF"

description: "Alarm condition active"

units: ""

Relay: object

value: "OFF"

description: "Relay state"

units: ""

AR: object

value: 0

description: "Alarm reason"

units: ""

BMV: object

value: 712

description: "Model description (deprecated)"

units: ""

FW: object

MON: object

H1: object

H2: object

H3: object

H4: object

H5: object

H6: object

H7: object

H8: object

H9: object

H10: object

H11: object

H12: object

H15: object

H16: object

H17: object

H18: object

this script gives me an error:
{"enc":true,"type":"error","data":{"name":"TypeError","message":"Cannot read properties of undefined (reading 'value')","stack":"TypeError: Cannot read properties of undefined (reading 'value')\n at Function node:16998054156cc482 [function 3]:8:20\n at Function node:16998054156cc482 [function 3]:32:3\n at Script.runInContext (node:vm:149:12)\n at processMessage (/usr/lib/node_modules/node-red/node_modules/@node-red/nodes/core/function/10-function.js:430:37)\n at FunctionNode._inputCallback (/usr/lib/node_modules/node-red/node_modules/@node-red/nodes/core/function/10-function.js:348:17)\n at /usr/lib/node_modules/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:214:26\n at Object.trigger (/usr/lib/node_modules/node-red/node_modules/@node-red/util/lib/hooks.js:166:13)\n at Node._emitInput (/usr/lib/node_modules/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:206:11)\n at Node.emit (/usr/lib/node_modules/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:190:25)"}}

It means somewhere in your Function node you are doing something like:

something.value

…but something is undefined at runtime.

Probably best to delete the fields or double-check the names match what is in function node.

Your data is already a JavaScript object, the json node is converting it to a string, which you don't want. Take out the json node.

You are right the output (in Influx) looks the same without the json node. But Influx still does not split the values.

Whenever you change the format of data stored in a measurement in influx you have to delete the measurement (or bucket or whatever they now call it) and start again.

You need to decide what measurements, fields and tags you want in the database, then format the data as described in the help page for the influxdb node.

I advice against using the Flux language, it was a mistake and is being dropped in influx v3.

I found a way that works for me. I used the change node to get the single values out of it.

Thanks for supporting me.

@Emmi
If you want to store multiple values ​​in the InfluxDB database (a bucket), you may use a function node instead of a change node.

See the following section of the "InfluxDB Out" node description:
" ... If msg.payload is an object containing multiple properties, the fields will be written to the measurement. ..."
Therefore you may use a function node with Javascript code like posted in #4 from @dynamicdave - without using any AI :wink:
For example, you can use the following reduced code:

let d = msg.payload;
msg.payload = {
    V_mV: d.V.value,
    T_C: d.T.value,
     I_mA: d.I.value,
     Alarm: d.Alarm.value,
};
return msg;

In InfluxDB v2.x, you can configure the measurement and bucket in the influxdb out node.

If you still prefer a change node, you must add an entry for each value to be stored in the database, e.g.
set msg.payload.V_mV to the value msg.payload.V.value
set msg.payload.T_C to the value msg.payload.T.value
...

My following suggestion is unsuitable, as @Colin noted - thanks so lot.
If you feed the entire payload object (for testing purposes) to the influxdb out node, you will be able to see via a query how the components of this object are stored in the database. This is at least worth testing.

Correction:
The elements located deeper within the data structure must be transferred to the first payload level, just as the short JavaScript snippet above demonstrates.

That will not work as the payload will still contain all the original properties. As in your function code it is necessary to first Move msg.payload To msg.d, then Set msg.payload to an empty object, and then Set the properties as you describe (from msg.d).

Thanks a lot for the proposal, but I won't touch it anymore, as it works like I did it above. I have the data I need already shown in grafana (and I'm running a bit out of time, as the ship wants to leave :face_with_peeking_eye: ). When there is more time I'll get a bit more into it.

But now I have a similar problem with an nmea data stream. I guess it's better to open a new thread. (First time for me asking a question in a forum.)

thanks a lot :heart_eyes:

I wasn't suggesting that you did change it, just pointing out the error in the post I referenced.